package hzmg.akkacloud.server.web.controller;

import cn.hutool.core.lang.Console;
import com.hzmg.akkacloud.common.exception.AkkaCloudException;
import com.hzmg.akkacloud.common.response.ResultDTO;
import hzmg.akkacloud.server.core.service.AppInfoService;
import hzmg.akkacloud.server.persistence.PageResult;
import hzmg.akkacloud.server.persistence.remote.model.AppInfoDO;
import hzmg.akkacloud.server.persistence.remote.repository.AppInfoRepository;
import hzmg.akkacloud.server.remote.worker.WorkerClusterQueryService;
import hzmg.akkacloud.server.web.request.AppAssertRequest;
import hzmg.akkacloud.server.web.request.AppInfoListRequest;
import hzmg.akkacloud.server.web.request.ModifyAppInfoRequest;
import hzmg.akkacloud.server.web.response.AppInfoVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * AppName Controller
 * vue axios 的POST请求必须使用 @RequestBody 接收
 *
 * @author zbw
 * @since 2022/7/25
 */
@RestController
@RequestMapping("/appInfo")
@Slf4j
public class AppInfoController {

    private static final int MAX_APP_NUM = 200;
    @Resource
    private AppInfoService appInfoService;
    @Resource
    private AppInfoRepository appInfoRepository;
    @Resource
    private WorkerClusterQueryService workerClusterQueryService;

    @PostMapping("/test")
    public void getAllService(@RequestParam(value = "first", required = false) Integer first,
                              @RequestParam(value = "second", required = false) double second,
                              @RequestParam(value = "third", required = false) int[] third,
                              @RequestParam(value = "fourth", required = false) Long[] fourth,
                              @RequestParam(value = "fifth", required = false) double[] fifth,
                              @RequestParam(value = "sixth", required = false) String[] sixth,
                              @RequestParam(value = "seven", required = false) List<String> seven,
                              @RequestParam(value = "eighth") Integer[] eighth) {
        workerClusterQueryService.getAppId2ClusterStatus()
                .forEach((test, test2) -> test2.getAllWorkers()
                        .forEach((s1, s2) -> Console.log(s2.toString())));
        log.info("[AppInfo] /test has been invoked");
    }

    @PostMapping("/test2")
    public void getAllService2(@RequestParam(value = "first", required = false, defaultValue = "1") int[] first) {
        log.info("[AppInfo]:test2-{}", Arrays.stream(first).toArray());
        workerClusterQueryService.getAppId2ClusterStatus()
                .forEach((test, test2) -> test2.getAllWorkers()
                        .forEach((s1, s2) -> Console.log(s2.toString())));
        log.info("[AppInfo] /test has been invoked");
    }

    private PageResult<AppInfoVO> convert(Page<AppInfoDO> data) {
        PageResult<AppInfoVO> newPage = new PageResult<>(data);
        newPage.setData(data.getContent().stream().map(appInfoDO -> AppInfoVO.from(appInfoDO, workerClusterQueryService)).collect(Collectors.toList()));
        return newPage;
    }

    @PostMapping("/save")
    public ResultDTO<Void> saveAppInfo(@RequestBody ModifyAppInfoRequest req) {

        req.valid();
        AppInfoDO appInfoDO;

        Long id = req.getId();
        if (id == null) {
            appInfoDO = new AppInfoDO();
            appInfoDO.setGmtCreate(new Date());
        } else {
            appInfoDO = appInfoRepository.findById(id).orElseThrow(() -> new IllegalArgumentException("can't find appInfo by id:" + id));

            // 对比密码
            if (!Objects.equals(req.getOldPassword(), appInfoDO.getPassword())) {
                throw new AkkaCloudException("The password is incorrect.");
            }
        }
        BeanUtils.copyProperties(req, appInfoDO);
        appInfoDO.setGmtModified(new Date());

        appInfoRepository.saveAndFlush(appInfoDO);
        return ResultDTO.success(null);
    }

    @PostMapping("/assert")
    public ResultDTO<Long> assertApp(@RequestBody AppAssertRequest request) {
        return ResultDTO.success(appInfoService.assertApp(request.getAppName(), request.getPassword()));
    }

    @GetMapping("/delete")
    public ResultDTO<Void> deleteAppInfo(Long appId) {
        appInfoRepository.deleteById(appId);
        return ResultDTO.success(null);
    }

    @PostMapping("/list")
    public ResultDTO<PageResult<AppInfoVO>> listAppInfo(@RequestBody AppInfoListRequest appInfoListRequest) {
        Pageable limit = PageRequest.of(appInfoListRequest.getPageNum(), appInfoListRequest.getPageSize());
        Page<AppInfoDO> afPage;
        if (StringUtils.isEmpty(appInfoListRequest.getAppName())) {
            afPage = appInfoRepository.findAll(limit);
            //Console.log(afPage.stream().limit(999)+""+appInfoRepository.findAll());
        } else {
            afPage = appInfoRepository.findByAppNameLike("%" + appInfoListRequest.getAppName() + "%", limit);
        }
        return ResultDTO.success(convert(afPage));
    }


}
